﻿using DNFImagePacks2Manager.Helpers;
using Microsoft.UI.Xaml.Media.Imaging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Graphics.Imaging;

namespace DNFImagePacks2Manager.QuickTool.Models
{
    public class ReplaceImage : INotifyPropertyChanged
    {
        public int Index { get; set; } = 0;
        public string Name { get; set; } = "";
        public List<string> Bind { get; set; } = [];
        public bool BindData{ get; set; } = false;
        public bool IsAnimate { get; set; } = false;
        public List<string> SubImage { get; set; } = [];
        public int AnimateDelay { get; set; } = 300;
        public string? Background { get; set; } = null;
        public string? Assets { get; set; } = null;
        public int Pointer { get; set; } = -1;
        public bool AllPointer {  get; set; } = false;
        public bool IsDisplay { get; set; } = true;
        public bool AssetsResize { get; set; } = false;
        public int Width { get; set; } = 0;
        public int Height { get; set; } = 0;
        public int FrameWidth
        {
            get => _frameWidth == 0 ? Width : _frameWidth;
            set => _frameWidth = value;
        }
        public int FrameHeight
        {
            get => _frameHeight == 0 ? Height : _frameHeight;
            set => _frameHeight = value;
        }
        public int PositionX { get; set; } = 0;
        public int PositionY { get; set; } = 0;
        public int OffsetX { get; set; } = 0;
        public int OffsetY { get; set; } = 0;

        private int _frameWidth = 0;
        private int _frameHeight = 0;

        public SoftwareBitmap? ImageBitmap { get; private set; } = null;
        public SoftwareBitmapSource? Image { get; private set; } = null;

        public event PropertyChangedEventHandler? PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private void SetReplaceImageWithoutResize(SoftwareBitmap originalImage)
        {
            ImageBitmap = originalImage;
        }

        public async void SetAssetsImage()
        {
            SoftwareBitmap? img;
            if (string.Equals(Assets, "transparent"))
            {
                if (AssetsResize)
                {
                    img = ImageHelper.CreateTransparentSoftwareBitmap(Width, Height);
                }
                else
                {
                    img = ImageHelper.CreateTransparentSoftwareBitmap(1, 1);
                }
            }
            else
            {
                string assetsFile = Path.Combine(AppContext.BaseDirectory, "QuickTool", "Assets", Assets ?? "NULL.png");
                img = await ImageHelper.ConvertImageToSoftwareBitmap(assetsFile);
                if (AssetsResize)
                {
                    img = StretchSoftwareBitmap(img);
                }
            }
            if (img != null)
            {
                SetReplaceImageWithoutResize(img);
            }
        }

        public void SetReplaceImage(SoftwareBitmap originalImage)
        {
            if (originalImage == null)
            {
                return;
            }

            if (Width <= 0 || Height <= 0)
            {
                SetReplaceImageWithoutResize(originalImage);
                return;
            }

            SoftwareBitmap? scaledBitmap = StretchSoftwareBitmap(originalImage);
            if (scaledBitmap == null)
            {
                SetReplaceImageWithoutResize(originalImage);
            }
            else
            {
                SetReplaceImageWithoutResize(scaledBitmap);
            }
        }

        public async void SetPreviewImage()
        {
            if (ImageBitmap != null)
            {
                Image = new SoftwareBitmapSource();
                await Image.SetBitmapAsync(ImageBitmap);
                OnPropertyChanged(nameof(Image));
            }
        }

        public async void SetPreviewImage(SoftwareBitmap image)
        {
            Image = new SoftwareBitmapSource();
            await Image.SetBitmapAsync(image);
        }

        public SoftwareBitmap? StretchSoftwareBitmap(SoftwareBitmap? originalImage)
        {
            if (originalImage == null)
            {
                return null;
            }
            try
            {
                SoftwareBitmap originalBgra;
                if (originalImage.BitmapPixelFormat != BitmapPixelFormat.Bgra8)
                {
                    originalBgra = SoftwareBitmap.Convert(
                        originalImage,
                        BitmapPixelFormat.Bgra8,
                        BitmapAlphaMode.Premultiplied
                    );
                }
                else
                {
                    originalBgra = originalImage;
                }

                int originalWidth = originalBgra.PixelWidth;
                int originalHeight = originalBgra.PixelHeight;
                byte[] originalPixels = new byte[originalWidth * originalHeight * 4];
                originalBgra.CopyToBuffer(originalPixels.AsBuffer());

                SoftwareBitmap scaledBitmap = new(
                    BitmapPixelFormat.Bgra8,
                    Width,
                    Height,
                    BitmapAlphaMode.Premultiplied
                );

                byte[] scaledPixels = new byte[Width * Height * 4];

                ImageHelper.StretchPixelsOptimized(
                    originalPixels, originalWidth, originalHeight,
                    scaledPixels, Width, Height,
                    LocalStorageHelper.GetGaussianBlur(),
                    LocalStorageHelper.GetInterpolationMode()
                );

                scaledBitmap.CopyFromBuffer(scaledPixels.AsBuffer());

                return scaledBitmap;
            }
            catch (Exception)
            {
                return originalImage;
            }
        }
    }
}
